package csci6450.chickenFriedFS.metaServer.threads;

import csci6450.chickenFriedFS.metaServer.MetaServerLog;
import csci6450.chickenFriedFS.metaServer.NuggetServerInfoLog;
import csci6450.chickenFriedFS.metaServer.RuntimeSettings;
import csci6450.chickenFriedFS.nuggetCore.NuggetServerInfo;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * This class is used to listenfor new NuggetServers joining the cluster.
 * @author jacobschoen
 */
public class MetaServerNuggetServerListener extends Thread {

    /**
     * Socket for this server to run on.
     */
    private ServerSocket nuggetServerRegister;

    // <editor-fold defaultstate="collapsed" desc=" UML Marker ">
    // #[regen=yes,id=DCE.3D8ECDEE-C845-9D58-12E2-7621FC57B17D]
    // </editor-fold>
    public MetaServerNuggetServerListener() throws IOException {
        this.nuggetServerRegister = new ServerSocket(RuntimeSettings.getInstance().getNuggetServerListenerPort());
        System.out.println("MetaServer listening for NuggetServer on port " + RuntimeSettings.getInstance().getNuggetServerListenerPort() + ".");

    }

    @Override
    public void run() {
        while (true) {
            try {
                Socket client = this.nuggetServerRegister.accept();
                Connect c = new Connect(client);
            } catch (Exception e) {
                Logger.getLogger(MetaServerClientListener.class.getName()).log(Level.SEVERE, null, e);
            }
        }
    }

    class Connect extends Thread {

        private Socket client = null;
        private ObjectInputStream inputStream = null;
        private ObjectOutputStream outputStream = null;

        public Connect() {
        }

        public Connect(Socket clientSocket) {
            this.client = clientSocket;
            try {
                this.inputStream = new ObjectInputStream(this.client.getInputStream());
                this.outputStream = new ObjectOutputStream(this.client.getOutputStream());
            } catch (Exception e1) {
                try {
                    this.client.close();
                } catch (Exception e) {
                    Logger.getLogger(Connect.class.getName()).log(Level.SEVERE, null, e);
                }
                return;
            }
            this.start();
        }

        @Override
        public void run() {
            try {
                NuggetServerInfo nuggetServer = (NuggetServerInfo) this.inputStream.readObject();
                if (nuggetServer != null) {
                    this.outputStream.writeObject("Success");
                    System.out.println("NuggetServer at IP "+nuggetServer.getIpAddress()+":"+nuggetServer.getMetaPort()+" added.");
                    //add it to the list of nuggetServers
                    NuggetServerInfoLog.getInstance().addNuggetServerInfo(nuggetServer);
                    if (nuggetServer.getNuggets() != null && nuggetServer.getNuggets().size() > 0) {
                        MetaServerLog.getInstance().addNuggets(nuggetServer.getNuggets());
                    }
                } else {
                    this.outputStream.writeObject("Fail");
                    System.out.println("NuggetServer at IP "+nuggetServer.getIpAddress()+":"+nuggetServer.getMetaPort()+" failed.");
                }

                // close streams and connections
                this.inputStream.close();
                this.outputStream.close();
                this.client.close();
            } catch (Exception e) {
                Logger.getLogger(Connect.class.getName()).log(Level.SEVERE, null, e);
            }
        }
    }
}
